package com.health.userbackstage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.health.userbackstage.mapper.*;
import com.health.userbackstage.mapper.relationmapper.OrderReportMapper;
import com.health.userbackstage.pojo.*;
import com.health.userbackstage.service.OrderService;
import com.health.userbackstage.service.OrderSettingService;
import com.health.userbackstage.utils.SnowflakeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @Author ASUS
 * @Date 2023/8/18 21:19
 * @Version 1.0
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private OrderReportMapper orm;

    @Autowired
    private SetMealMapper smm;

    @Autowired
    private MemberMapper mm;

    @Autowired
    private OrderMapper om;

    @Autowired
    private OrderSettingMapper osm;

    @Autowired
    private SimpleDateFormat sdf;

    @Autowired
    private ReportMapper rm;

    @Override
    public PageOrder findPage(Integer currentPage, Integer pageSize, String queryString, Date queryDate) {
        PageOrder po = new PageOrder();
        String date = null;
        if (queryDate != null && !"".equals(queryDate)) {
            date = (queryDate.getYear() + 1900) + "-" + (queryDate.getMonth() + 1) + "-" + queryDate.getDate();
        }
        int total = om.findCount(queryString, date);
        po.setTotal(total);
        if (total == 0) {
            total = 1;
        }
        if (currentPage > Math.ceil(total / pageSize)) {
            currentPage = (int) Math.ceil((double) total / pageSize);
        }

        po.setCurrentPage(currentPage);
        po.setPageSize(pageSize);
        List<Order> list = om.findPage((currentPage - 1) * pageSize, pageSize, queryString, date);
        po.setList(list);
        return po;
    }

    @Override
    public void delBySetMealId(Integer id) {
        om.delBySetMealId(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
//    改为用锁来解决并发
    public synchronized boolean add(Order order) {
//        修改后的预约详情 用来查看预约数是否超了
        OrderSetting orderDateSetting = osm.findOne(sdf.format(order.getOrderDate()));
//        如果预约数不够 不允许预约当天
        if (orderDateSetting.getNumber() > orderDateSetting.getReservations()) {
////            需要乐观锁控制并发情况 先修改 成功后新增order 并新增report
//            order.setOrderSettingVersion(orderDateSetting.getVersion());
            osm.increaseReservations(order);
//            if (effectCount == 1) {
//                新增预约
            om.add(order);
//                新增report
            Report report = new Report();
            report.setMemberId(order.getMemberId());
            Member member = mm.findNameById(order.getMemberId());
            report.setName(member.getName());
            report.setSex(member.getSex());
            report.setHealthDate(order.getOrderDate());
            String setMealName = smm.getSetMealNameById(order.getSetMealId());
            report.setSetMealName(setMealName);
            SnowflakeUtils su = new SnowflakeUtils();
            report.setFileNumber(su.nextId());
            rm.add(report);
//                根据report id 在对应关系表中新增一条
            orm.add(order.getId(), report.getId());
            return true;
//            }
        }
        return false;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized boolean edit(Order order) {
//        获取原来的预约对象 需要该对象的日期 事务时需要原来的日期-1 改动后的日期+1
        Order oldOrder = om.findOrderById(order.getId());

//        对report表修改 通过对应关系表找到report 先改套餐和状态 剩下日期做判断
        Report report = orm.findReportByOid(order.getId());
        String setMealName = smm.getSetMealNameById(order.getSetMealId());
        report.setSetMealName(setMealName);
        report.setOrderStatus(order.getOrderStatus());

        //如果日期相同 直接修改即可
        if (oldOrder.getOrderDate().equals(order.getOrderDate())) {
            om.edit(order);
            report.setHealthDate(order.getOrderDate());
            rm.edit(report);
            return true;
//            如果日期不相同
        } else {
            //        修改后的日期的预约详情 用来查看预约数是否超了
            OrderSetting orderDateSetting = osm.findOne(sdf.format(order.getOrderDate()));
//        如果预约数不够 不允许预约当天
            if (orderDateSetting.getNumber() > orderDateSetting.getReservations()) {
////        根据id修改 需要乐观锁
//                order.setOrderSettingVersion(orderDateSetting.getVersion());
                osm.increaseReservations(order);
//                if (edit == 1) {
                //如果成功抢占预约设置表的预约数 则修改和减少原日期预约数
                om.edit(order);
                osm.reduceReservations(oldOrder);
//                report也需要修改日期
                report.setHealthDate(order.getOrderDate());
                rm.edit(report);
                return true;
//                }
            }//如果预约数不够 放行到false
            return false;
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
//    此处是orderid
    public void del(Integer id) {
//        需要删除对应report报表
        Order oldOrder = om.findOrderById(id);
        om.del(id);
        osm.reduceReservations(oldOrder);
//        根据orderid在对应表找到reportid并删除
        Report report = orm.findReportByOid(id);
        rm.del(report.getId());
//        把关系表的数据也删了
        orm.del(id,report.getId());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public boolean deleteById(Integer id) {
        int i = om.deleteById1(id);
        if(i > 0){
            return true;
        }
        return false;
    }

}
